/**
 * @file       main.c
 * @author     mz8023yt
 * @email      mz8023yt@163.com
 * @version    V1.0
 * @date       2022-03-13
 * @brief      st7735 lcd test
 */

#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "st7735.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>

static spi_device_handle_t spi;

void esp32c3_rst_pin(int val)
{
	gpio_set_level(10, val);
}

void esp32c3_dc_pin(int val)
{
	gpio_set_level(6, val);
}

void esp32c3_bl_pin(int val)
{
	gpio_set_level(11, val);
}

void esp32c3_msleep(int ms)
{
	usleep(1000 * ms);
}

void esp32c3_spi_write(uint8_t* bytes, uint32_t len)
{
	spi_transaction_t t;

	memset(&t, 0, sizeof(t));             // Zero out the transaction
	t.length = len * 8;                   // Command is 8 bits
	t.tx_buffer = bytes;                  // The data is the cmd itself
	spi_device_polling_transmit(spi, &t); // Transmit!
}

void board_init()
{
	/* gpio */
	gpio_reset_pin(10);
	gpio_set_direction(10, GPIO_MODE_OUTPUT);
	gpio_reset_pin(6);
	gpio_set_direction(6, GPIO_MODE_OUTPUT);
	gpio_reset_pin(11);
	gpio_set_direction(11, GPIO_MODE_OUTPUT);

	spi_bus_config_t buscfg = {
		.miso_io_num = 0,
		.mosi_io_num = 3,
		.sclk_io_num = 2,
		.quadwp_io_num = -1,
		.quadhd_io_num = -1,
		.max_transfer_sz = 16,
	};

	spi_device_interface_config_t devcfg = {
		.clock_speed_hz = 10000000, // Clock out at 10 MHz
		.mode = 0,                  // SPI mode 0
		.spics_io_num = 7,          // CS pin
		.queue_size = 7,            // We want to be able to queue 7 transactions at a time
	};

	spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO);
	spi_bus_add_device(SPI2_HOST, &devcfg, &spi);
}

void app_main(void)
{
	struct st7735 lcd;

	board_init();

	/* set lcd param */
	lcd.cfg.fix.width = 80;
	lcd.cfg.fix.height = 160;
	lcd.cfg.var.orien = 0;

	/* register the operation */
	lcd.ops.pin.rst = esp32c3_rst_pin;
	lcd.ops.pin.dc = esp32c3_dc_pin;
	lcd.ops.pin.bl = esp32c3_bl_pin;
	lcd.ops.time.msleep = esp32c3_msleep;
	lcd.ops.spi.write = esp32c3_spi_write;
	st7735_init(&lcd);

	while (1) {
		st7735_screen_test(&lcd, RGB565_WHITE);
		vTaskDelay(1000 / portTICK_PERIOD_MS);

		st7735_screen_test(&lcd, RGB565_RED);
		vTaskDelay(1000 / portTICK_PERIOD_MS);
	}
}